﻿using System;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
using System.Diagnostics;
using Abp.Domain.Entities;
using Abp.Domain.Entities.Auditing;
using Abp.Extensions;
using JetBrains.Annotations;

namespace DHJ.Cost.Tasks
{
    /// <summary>
    ///     投批任务，Id为条码号
    /// </summary>
    public sealed class Batch : Entity<string>, IHasCreationTime
    {
        [UsedImplicitly]
        public Batch()
        {
        }

        public Batch(string id,
            long taskId,
            int quantity,
            string qcCard,
            string parentId = null,
            int? parentQuantity = null,
            string childDrawingNum = null,
            string childTaskName = null
            )
        {
            Id = id;
            TaskId = taskId;
            Quantity = quantity;
            QcCard = qcCard;
            ParentId = parentId;
            ParentQuantity = parentQuantity;
            ChildTaskName = childTaskName;
            ChildDrawingNum = childDrawingNum;
            ManufacturingState = ManufacturingState.Manufacturing;
            AccountingState = AccountingState.Active;
        }

        /// <summary>
        ///     投产数量
        ///     随着条码分码会减少
        /// </summary>
        public int Quantity { get; set; }

        /// <summary>
        ///     任务Id
        /// </summary>
        public long TaskId { get; set; }

        [ForeignKey("TaskId")]
        public Task Task { get; set; }

        /// <summary>
        /// 部装子任务名称
        /// </summary>
        public string ChildTaskName { get; set; }

        /// <summary>
        /// 部装子任务图号
        /// </summary>
        public string ChildDrawingNum { get; set; }

        /// <summary>
        ///     质控卡号
        /// </summary>
        [Required]
        public string QcCard { get; set; }

        /// <summary>
        ///     父条码
        /// </summary>
        public string ParentId { get; set; }

        /// <summary>
        ///     分码时父条码的数量
        /// </summary>
        public int? ParentQuantity { get; set; }

        /// <summary>
        ///     完工状态
        /// </summary>
        public ManufacturingState ManufacturingState { get; set; }

        /// <summary>
        ///     核算状态
        /// </summary>
        public AccountingState AccountingState { get; set; }

        /// <summary>
        ///     合格证号
        /// </summary>
        public string Certificate { get; set; }

        /// <summary>
        ///     合格数量
        /// </summary>
        public int QualifiedQuantity { get; set; }

        /// <summary>
        ///     库存数量
        /// </summary>
        public int StockQuantity { get; set; }

        /// <summary>
        ///     创建时间
        /// </summary>
        public DateTime CreationTime { get; set; }

        //[ForeignKey("BatchId")]
        //public virtual ICollection<AllocRel> AllocRels { get; set; }

        //[ForeignKey("AssemId")]
        //public virtual ICollection<AssemRel> AssemRels { get; set; }

        /// <summary>
        ///     任务完工
        /// </summary>
        /// <param name="certificate">合格证号</param>
        /// <param name="qualifiedQuantity">合格数量</param>
        public void CompleteTask(string certificate, int qualifiedQuantity)
        {
            ManufacturingState = ManufacturingState.Completed;
            Certificate = certificate;
            QualifiedQuantity = qualifiedQuantity;
            StockQuantity = qualifiedQuantity;
        }

        /// <summary>
        ///     减少条码对应产品数量，一般原因是条码分码。
        /// </summary>
        public void DecreaseQuantity(int amount)
        {
            if (Quantity < amount) throw new ApplicationException("条码数量不能小于0.");

            Quantity -= amount;
        }

        /// <summary>
        ///     零件出库
        /// </summary>
        public void StockOut(int amount)
        {
            if (StockQuantity < amount) throw new ApplicationException("库存不足");

            StockQuantity -= amount;
        }

        public void FreezeTask()
        {
            AccountingState = AccountingState.Frozen;
        }

        public BatchIdentifier ToBatchIdentifier()
        {
            return new BatchIdentifier(Id, Quantity);
        }

        /// <summary>
        ///     返回父条码的<see cref="BatchIdentifier" />实体。
        ///     如果没有父条码则返回Null。
        /// </summary>
        public BatchIdentifier ParentIdentifier()
        {
            if (ParentId.IsNullOrWhiteSpace()) return null;
            Debug.Assert(ParentQuantity != null, nameof(ParentQuantity) + " != null");
            return new BatchIdentifier(ParentId, ParentQuantity.Value);
        }
    }
}